/*
    Copyright is LuoYuShun to 2022-2022
*/
package cn.com.laya.service.fourdemo.deals.websocket;

import cn.com.laya.service.fourdemo.bean.ResultResponse;
import cn.com.laya.service.fourdemo.bean.WebSocketMessage;
import cn.com.laya.service.fourdemo.deals.MessageDealHandler;
import cn.com.laya.service.fourdemo.deals.WebSocketMessageFactory;
import cn.com.laya.service.fourdemo.utils.WebSocketUtils;
import cn.com.laya.service.fourdemo.websocket.WebSocket;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.ConcurrentMap;
import java.util.function.Consumer;

/**
 * WebSocket的消息处理
 *
 * @author LuoYuShun
 * @since 2022-11-24
 */
@Slf4j
public abstract class WebSocketMessageHandler implements MessageDealHandler {

    @Override
    public boolean isHandler(String messageType, String handlerType) {
        return WebSocketMessageFactory.WEB_SOCKET_HANDLER_TYPE.equals(handlerType) && isHandler(messageType);
    }

    /**
     * 主动推送消息
     *
     * @param webSocketMessage web的信息
     * @param fallBackInvoke 回调
     * @param webSocket web socket
     * @param actionMap 动作的map数据容器
     */
    protected void sendMessage(WebSocketMessage webSocketMessage, Consumer<ResultResponse<?>> fallBackInvoke,
                               WebSocket webSocket, ConcurrentMap<String, WebSocketMessage> actionMap) {
        actionMap.put(webSocketMessage.getAccount(), webSocketMessage);
        webSocket.setScenario(webSocketMessage.getScenario());
        List<WebSocket> webSocketClient = WebSocketUtils.getWebSocketClient(webSocketMessage.getScenario());
        WebSocketUtils.sendMessage(JSON.toJSONString(Collections.singletonList(webSocketMessage)), webSocketClient);
        if (Objects.nonNull(fallBackInvoke)) {
            fallBackInvoke.accept(ResultResponse.success("发送成功"));
        }
    }

    /**
     * 判断是否有权限
     *
     * @param webSocketMessage 消息
     * @param webSocket web的socket
     * @param fallBackInvoke 回调
     * @return 返回权限登录的状态
     */
    protected boolean isAuthLogin(
            WebSocketMessage webSocketMessage, WebSocket webSocket, Consumer<ResultResponse<?>> fallBackInvoke) {
        if (Objects.isNull(webSocket)) {
            log.error("没有进行登录，请登录 {}", webSocketMessage.getAccount());
            if (Objects.nonNull(fallBackInvoke)) {
                fallBackInvoke.accept(ResultResponse.authError("没有进行登录，请进行登录"));
            }
            return false;
        }
        return true;
    }

    /**
     * 判断是否是这个处理器
     *
     * @param messageType 消息的类型
     * @return 返回是否符合这个处理器
     */
    protected abstract boolean isHandler(String messageType);

    @Override
    public <S> void dealMessage(S message, Consumer<ResultResponse<?>> fallBackInvoke) {
        WebSocketMessage webSocketMessage = null;
        // 进行参数的类型的转换
        if (message instanceof WebSocketMessage) {
            webSocketMessage = (WebSocketMessage) message;
        }
        if (Objects.isNull(webSocketMessage)) {
            log.error("传入的参数类别不对，是否的调错的处理器了！{}", JSON.toJSONString(message));
        }
        // 调用处理消息的数据信息
        handlerMessage(webSocketMessage, fallBackInvoke);
    }

    /**
     * 处理信息
     *
     * @param webSocketMessage 消息
     * @param fallBackInvoke 回调
     */
    protected abstract void handlerMessage(WebSocketMessage webSocketMessage, Consumer<ResultResponse<?>> fallBackInvoke);
}
